﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace IntegratedOnBordDebug
{
    public class CPPBox : IDisposable
    {
        private static volatile CPPBox cppbox;
        private static readonly object lockHelper = new object();
        public UDPAsync UdpAsyncClient = null;
        public string URLPrefix = "http://";

        public static CPPBox Init(string ListenIP = "")
        {
            if (cppbox == null)
            {
                lock (lockHelper)
                {
                    if (cppbox == null)
                    {
                        cppbox = new CPPBox(ListenIP);
                    }
                }
            }
            return cppbox;
        }
        
        /// <summary>
        /// 监听中的IPv4
        /// </summary>
        public string ListeningIPv4
        {
            get { return UdpAsyncClient.LocalListenIP; }
        }

        /// <summary>
        /// 监听端口
        /// </summary>
        public int ListeningPort
        {
            get { return UdpAsyncClient.PortToListenTo; }
        }

        public static void UnInit()
        {
            if (cppbox != null)
            {
                lock (lockHelper)
                {
                    if (cppbox.UdpAsyncClient != null)
                    {
                        cppbox.UdpAsyncClient.StopListener();
                    }
                }

                cppbox = null;
            }
        }

        private CPPBox(string sListenIP = "")
        {
            UdpAsyncClient = new UDPAsync(0, 80, sListenIP);
        }

        /// <summary>
        /// 发送帮助按钮确认指令
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendHelpAnswer(string pIPAddress)
        {
            return SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_PARK_T_HELP, null);
        }

        /// <summary>
        /// 重启扫码模块
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendScannerReset(string pIPAddress)
        {
            return SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_PARK_RESET_SCANNER, null);
        }

        /// <summary>
        /// 扩展设备消息订阅
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <param name="subIPAddress">订阅者IP</param>
        /// <param name="subPort">订阅者端口</param>
        /// <returns></returns>
        public bool SendSubscribe(string pIPAddress, string subIPAddress, int subPort)
        {
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("uIpv4Addr", subIPAddress);//语音播报类型
            dictParams.Add("uPort", subPort);       //大小
            return SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_SUBSCRIBE, dictParams);
        }

        /// <summary>
        /// 设备搜索
        /// </summary>
        /// <returns></returns>
        public bool SendSearchDevice()
        {
            bool flag = false;
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            flag = SendToUdp("", InfoEnumClass.EmCommandID.CMD_BASIC_SEARCHDEVICE, dictParams, true);
            return flag;
        }

        /// <summary>
        /// 发送广播修改IP
        /// </summary>        
        /// <param name="uIpv4Addr">Ipv4的地址</param>
        /// <param name="uIpv4Mask">Ipv4的子网掩码</param>
        /// <param name="uIpv4Gateway">Ipv4的网关地址</param>
        /// <param name="byMac">MAC地址 AA:BB:CC:DD:EE:FF</param>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendEditIP(string uIpv4Addr, string uIpv4Mask, string uIpv4Gateway, string byMac, string pIPAddress = "")
        {
            bool result = new bool();
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("uIpv4Addr", uIpv4Addr);
            dictParams.Add("uIpv4Mask", uIpv4Mask);
            dictParams.Add("uIpv4Gateway", uIpv4Gateway);
            dictParams.Add("byMac", byMac);
            result = SendToUdp("", InfoEnumClass.EmCommandID.CMD_BASIC_UDPMODIFYIP, dictParams, true);
            return result;
        }

        /// <summary>
        /// 响应心跳消息
        /// </summary>
        /// <param name="IpAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendAckHeartBeat(string IpAddress)
        {
            bool result = new bool();
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            result = SendToUdp(IpAddress, InfoEnumClass.EmCommandID.CMD_BASIC_HEARTBEAT, dictParams, false);
            return result;
        }

        /// <summary>设置485串口信息
        /// 
        /// </summary>
        /// <param name="IpAddress">一体机IP</param>
        /// <param name="Port">波特率代码：00-4800，01-9600，02-19200，03-57600，04-115200；</param>
        /// <returns></returns>
        public bool SendSetSerial485(string IpAddress, int Port)
        {
            bool flag = false;
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("uSpeed", Port);
            flag = SendToUdp(IpAddress, InfoEnumClass.EmCommandID.CMD_BASIC_SET_SERIAL485, dictParams, false);
            return flag;
        }

        /// <summary>获取485串口信息
        /// 
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendUdpGetSerial485(string pIPAddress)
        {
            //数值(HEX) 00   01   02    03    04
            //波特率   4800 9600 19200 57600 115200

            bool result = new bool();
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            //result = ClientSendByUdp(InfoEnumClass.EmCommandID.CMD_BASIC_GET_SERIAL485, dictParams);
            result = SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_BASIC_GET_SERIAL485, dictParams, false);
            return result;
        }


        /// <summary>设置补光灯开启和关闭时间
        /// 
        /// </summary>
        /// <param name="IpAddress">一体机IP</param>
        /// <param name="EnableLight">false：时间不生效 true：时间生效，按设置的时间亮灭</param>
        /// <param name="HourOn">亮灯时(0~23)</param>
        /// <param name="MinuteOn">亮灯分(0~59)</param>
        /// <param name="HourOff">灭灯时(0~23)</param>
        /// <param name="MinuteOff">灭灯分(0~59)</param>
        /// <returns></returns>
        public bool SendSetExtralLight(string IpAddress, bool EnableLight, int HourOn, int MinuteOn, int HourOff, int MinuteOff)
        {
            bool flag = false;
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            byte enableLight = (byte)(EnableLight ? 0x01 : 0x00);
            dictParams.Add("EnableLight", enableLight);
            dictParams.Add("HourOn", HourOn);
            dictParams.Add("MinuteOn", MinuteOn);
            dictParams.Add("HourOff", HourOff);
            dictParams.Add("MinuteOff", MinuteOff);

            //flag = ClientSendByUdp(InfoEnumClass.EmCommandID.CMD_PARK_SET_EXTRA_LIGHT, dictParams);
            flag = SendToUdp(IpAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_EXTRA_LIGHT, dictParams, false);
            return flag;
        }

        /// <summary>
        /// 发送查询补光灯设置信息
        /// </summary>
        /// <param name="IpAddress"></param>
        /// <returns></returns>
        public bool SendGetExtralLight(string IpAddress)
        {
            bool flag = false;
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            //flag = ClientSendByUdp(InfoEnumClass.EmCommandID.CMD_PARK_GET_EXTRA_LIGHT, dictParams);
            flag = SendToUdp(IpAddress, InfoEnumClass.EmCommandID.CMD_PARK_GET_EXTRA_LIGHT, dictParams, false);
            return flag;
        }

        /// <summary>发送设置网络信息命令
        /// 
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <param name="uIpv4Addr">Ipv4的地址</param>
        /// <param name="uIpv4Mask">Ipv4的子网掩码</param>
        /// <param name="uIpv4Gateway">Ipv4的网关地址</param>
        /// <param name="byMac">MAC地址 AA:BB:CC:DD:EE:FF</param>
        /// <returns></returns>
        public bool SendSetNetWork(string pIPAddress, string uIpv4Addr, string uIpv4Mask, string uIpv4Gateway, string byMac)
        {
            bool result = new bool();
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("uIpv4Addr", uIpv4Addr);
            dictParams.Add("uIpv4Mask", uIpv4Mask);
            dictParams.Add("uIpv4Gateway", uIpv4Gateway);
            dictParams.Add("byMac", byMac);
            //result = ClientSendByUdp(InfoEnumClass.EmCommandID.CMD_BASIC_SET_NETWORK, dictParams);
            result = SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_BASIC_SET_NETWORK, dictParams, false);
            return result;
        }

        /// <summary>
        /// 恢复网络默认参数
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendSetDefaultNet(string pIPAddress)
        {
            bool result = new bool();

            //result = ClientSendByUdp(InfoEnumClass.EmCommandID.CMD_BASIC_RECOVERY, null);
            result = SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_BASIC_RECOVERY, new Dictionary<string, object>(), false);
            return result;
        }

        ///<summary>发送获取设备网络信息命令
        /// 
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendGetDeviceNet(string pIPAddress)
        {
            bool result = new bool();

            result = SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_BASIC_GET_NETWORK, new Dictionary<string, object>(), false);
            return result;
        }

        ///<summary>发送获取设备基本信息命令
        /// 
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendGetDeviceInfo(string pIPAddress)
        {
            bool result = new bool();

            result = SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_BASIC_GET_SYSTEM, new Dictionary<string, object>(), false);
            return result;
        }

        /// <summary>发送重启命令
        /// 
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendRestart(string pIPAddress)
        {
            bool result = new bool();

            result = SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_BASIC_REBOOT, new Dictionary<string, object>(), false);
            return result;
        }

        /// <summary>发送校时命令
        /// 
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendSetDateTime(string pIPAddress, Dictionary<string, object> dictParams)
        {
            bool result = new bool();

            result = SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_BASIC_SET_TIME, dictParams);
            return result;
        }

        public bool SendSetDateTime(string pIPAddress, DateTime dateTimeSet)
        {
            bool result = new bool();

            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            DateTime dtNow = dateTimeSet;
            byte year = (byte)(dtNow.Year % 100);
            byte month = (byte)dtNow.Month;
            byte day = (byte)dtNow.Day;
            byte hour = Convert.ToByte(dtNow.ToString("HH"));
            byte minute = (byte)dtNow.Minute;
            byte second = (byte)dtNow.Second;

            dictParams.Add("pYear", year);
            dictParams.Add("pMonth", month);
            dictParams.Add("pDay", day);
            dictParams.Add("pHour", hour);
            dictParams.Add("pMinute", minute);
            dictParams.Add("pSecond", second);
            result = SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_BASIC_SET_TIME, dictParams);
            return result;
        }

        /// <summary>发送获取时间命令
        /// 
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <returns></returns>
        public bool SendGetDateTime(string pIPAddress)
        {
            bool result = new bool();

            result = SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_BASIC_GET_TIME, new Dictionary<string, object>());
            return result;
        }

        //语音信息
        public bool SendSetVoice(string pIPAddress, Dictionary<string, object> dictParams)
        {

            return SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_VOICEBROADCAST, dictParams);
        }

        /// <summary>设置语音播报信息
        /// 
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <param name="byContentType"> 0：播放收费金额；1：播放欢迎光临；2：播放一路平安；3：播放月租用户到期提醒；4: 播放剩余金额；5：过期提醒；</param>
        /// <param name="byVolume">语音大小 （0~7）</param>
        /// <param name="byType">语音播报类型 0-男声 1-女声</param>
        /// <param name="fCharges">收费金额或到期剩余天数，当 byContentType 0时-fCharges对应收费金额；3时-fCharges对应月租用户到期剩余天数；4时-fCharges对应剩余金额；</param>
        /// <returns></returns>
        public bool SendSetVoice(string pIPAddress, int byContentType, int byVolume, int byType, float fCharges)
        {

            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("byContentType", byContentType);//语音播报类型
            dictParams.Add("byVolume", byVolume);   //大小
            dictParams.Add("byType", byType);       //类型
            dictParams.Add("fCharges", fCharges);   //金额
            return SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_VOICEBROADCAST, dictParams);
        }

        /// <summary>发送设置设备闸杆消息
        /// 
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <param name="action">闸杆动作  0-落杆 1-起杆</param>
        /// <returns></returns>
        public bool SendSetBrakeBar(string pIPAddress, int action)
        {

            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("byControl", action);
            return SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_BRAKE, dictParams);
        }

        /// <summary>
        /// 设置LED显示屏开关
        /// </summary>
        /// <param name="pIPAddress">一体机IP</param>
        /// <param name="State">true 开，false 关</param>
        /// <returns></returns>
        public bool SendSetLedOnOff(string pIPAddress, bool State)
        {
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("SwitchOnOff", State ? 0x01 : 0x00);
            return SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_LEDSWITCH, dictParams);
        }

        /// <summary>设置屏类型
        /// 
        /// </summary>
        /// <param name="ip">一体机IP</param>
        /// <param name="ledType">0-16*64点阵屏 1-32*64点阵屏 2-64*128点阵屏</param>
        /// <returns></returns>
        public bool SendSetLedType(string ip, int ledType)
        {
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("uCommand", 1);
            dictParams.Add("uSelectedIndex", ledType);
            dictParams.Add("uKeepTime", 0);
            return SendSetLed(ip, dictParams);
        }

        /// <summary>发送LED显示或配置
        /// 
        /// </summary>
        /// <param name="pIPAddress"></param>
        /// <param name="dictParams"></param>
        /// <returns></returns>
        public bool SendSetLed(string pIPAddress, Dictionary<string, object> dictParams)
        {

            return SendToUdp(pIPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_LED, dictParams);
        }

        /// <summary>16*64点阵屏显示设置
        /// 
        /// </summary>
        /// <param name="ip">一体机IP</param>
        /// <param name="keepTime">发布的内容保持时间范围0~255，单位秒，超时之后恢复默认显示；等于0时，表示内容保持时间无限长；</param>
        /// <param name="freshTime">多屏显示切换时间，单位秒，范围1至60</param>
        /// <param name="OneMsg">显示内容（8字节倍数）</param>
        /// <param name="cmdType">设置命令类型：00-查询屏幕类型 01-设置屏幕类型 02-发布显示内容 03-发布默认显示内容（断电保存） 04-发布默认显示内容（断电不保存）</param>
        /// <param name="OneShowTime">第一行是否显示时间：0 不显示；1 显示；</param>
        /// <param name="OneTimePos">第一行日期显示位置：0 内容前；1 内容后；</param>
        /// <param name="OneTimeFormat">内容格式：0 yy年MM月dd日；1 yy-MM-dd；2 yy/MM/dd；3 yy.MM.dd；4 H时mm分ss秒 (24小时制)；5 HH时mm分ss秒 (12小时制)；6 HH:mm:ss (24小时制)；7 H:mm:ss (12小时制)；</param>
        /// <param name="OneEffect">第一行动画特效：0-静态多屏切换；2-左移；</param>
        public void SendSetLed16Ride64Show(string ip, int keepTime, int freshTime, string OneMsg, int cmdType = 2, int OneShowTime = 0, int OneTimePos = 0, int OneTimeFormat = 0, int OneEffect = 0)
        {
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            /* 00-查询屏幕类型 01-设置屏幕类型 02-发布显示内容 03-发布默认显示内容 */
            dictParams.Add("uCommand", cmdType);
            dictParams.Add("uSelectedIndex", 0); //0-16*64点阵屏,1-32*64点阵屏,2-64*128点阵屏
            dictParams.Add("uKeepTime", keepTime);
            dictParams.Add("uReserve", 0);

            //第一行
            dictParams.Add("uLineNumber", 0);
            dictParams.Add("uLedChangeTime", freshTime);
            dictParams.Add("uLedScreenSum", 0);
            dictParams.Add("OneEffect", OneEffect); //特效
            dictParams.Add("uLedMsg", OneMsg);
            dictParams.Add("OneShowTime", OneShowTime);
            dictParams.Add("OneTimePos", OneTimePos);
            dictParams.Add("OneTimeFormat", OneTimeFormat);

            SendSetLed(ip, dictParams);
        }

        /// <summary>32*64点阵屏显示设置
        /// 
        /// </summary>
        /// <param name="ip">一体机IP</param>
        /// <param name="keepTime">发布的内容保持时间范围0~255，单位秒，超时之后恢复默认显示；等于0时，表示内容保持时间无限长；</param>
        /// <param name="freshTime">多屏显示切换时间，单位秒，范围1至60</param>
        /// <param name="OneMsg">第一行显示内容（8字节倍数）</param>
        /// <param name="TwoMsg">第二行显示内容（8字节倍数）</param>
        /// <param name="cmdType">设置命令类型：00-查询屏幕类型 01-设置屏幕类型 02-发布显示内容 03-发布默认显示内容（断电保存） 04-发布默认显示内容（断电不保存）</param>
        /// <param name="OneShowTime">第一行是否显示时间：0 不显示；1 显示；</param>
        /// <param name="OneTimePos">第一行日期显示位置：0 内容前；1 内容后；</param>
        /// <param name="OneTimeFormat">内容格式：0 yy年MM月dd日；1 yy-MM-dd；2 yy/MM/dd；3 yy.MM.dd；4 H时mm分ss秒 (24小时制)；5 HH时mm分ss秒 (12小时制)；6 HH:mm:ss (24小时制)；7 H:mm:ss (12小时制)；</param>
        /// <param name="TwoShowTime">第二行是否显示时间：0 不显示；1 显示；</param>
        /// <param name="TwoTimePos">第二行日期显示位置：0 内容前；1 内容后；</param>
        /// <param name="TwoTimeFormat">第二行内容格式：0 yy年MM月dd日；1 yy-MM-dd；2 yy/MM/dd；3 yy.MM.dd；4 H时mm分ss秒 (24小时制)；5 HH时mm分ss秒 (12小时制)；6 HH:mm:ss (24小时制)；7 H:mm:ss (12小时制)；</param>
        /// <param name="OneEffect">第一行动画特效：0-静态多屏切换；2-左移；</param>
        /// <param name="TwoEffect">第二行动画特效：0-静态多屏切换；2-左移；</param>
        public void SendSetLed32Ride64Show(string ip, int keepTime, int freshTime, string OneMsg, string TwoMsg, int cmdType = 2, int OneShowTime = 0, int OneTimePos = 0, int OneTimeFormat = 0, int TwoShowTime = 0, int TwoTimePos = 0, int TwoTimeFormat = 0, int OneEffect = 0, int TwoEffect = 0)
        {
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("uCommand", cmdType);
            dictParams.Add("uSelectedIndex", 1); //0-16*64点阵屏,1-32*64点阵屏,2-64*128点阵屏
            dictParams.Add("uKeepTime", keepTime);
            dictParams.Add("uReserve", 0);

            //第一行
            dictParams.Add("uLineNumber", 0);
            dictParams.Add("uLedScreenSum", 0);
            dictParams.Add("OneEffect", OneEffect); //特效
            dictParams.Add("uLedChangeTime", freshTime);
            dictParams.Add("uLedMsg", OneMsg);
            dictParams.Add("OneShowTime", OneShowTime);
            dictParams.Add("OneTimePos", OneTimePos);
            dictParams.Add("OneTimeFormat", OneTimeFormat);

            //第二行
            dictParams.Add("uLineNumber2", 1);
            dictParams.Add("uLedScreenSum2", 0);
            dictParams.Add("TwoEffect", TwoEffect); //特效
            dictParams.Add("uLedChangeTime2", freshTime);
            dictParams.Add("uLedMsg2", TwoMsg);
            dictParams.Add("TwoShowTime", TwoShowTime);
            dictParams.Add("TwoTimePos", TwoTimePos);
            dictParams.Add("TwoTimeFormat", TwoTimeFormat);

            SendSetLed(ip, dictParams);
        }

        /// <summary>发送查询屏类型命令
        /// 
        /// </summary>
        /// <param name="ip">一体机IP</param>
        /// <returns></returns>
        public bool SendGetLedType(string ip)
        {

            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("uCommand", 0);
            return SendSetLed(ip, dictParams);
        }

        /// <summary>
        /// 显示控制一体机字库下载
        /// </summary>
        /// <param name="IPAddress">一体机IP</param>
        /// <param name="BagTotal">包总数，从0 开始计数</param>
        /// <param name="BagNum">当前包索引，从0开始计数</param>
        /// <param name="FontLibBytes">当前包数据，长度不大于256</param>
        /// <returns></returns>
        public bool DownLoadFontLibByUdp(string IPAddress, uint BagTotal, uint BagNum, byte[] FontLibBytes)
        {
            bool flag = false;
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            uint bagTotal = BagTotal;    //包总数 0
            uint bagNum = BagNum;    //当前包索引
            dictParams.Add("bagTotal", bagTotal);
            dictParams.Add("bagNum", bagNum);
            dictParams.Add("bagBuff", FontLibBytes);
            flag = SendToUdp(IPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_CHARSLIB, dictParams);
            return flag;
        }

        /// <summary>
        /// 远程程序下载命令
        /// </summary>
        /// <param name="IPAddress">一体机IP</param>
        /// <param name="BagTotal">包总数，从0 开始计数</param>
        /// <param name="BagNum">当前包索引，从0开始计数</param>
        /// <param name="FontLibBytes">当前包数据，长度不大于256</param>
        /// <returns></returns>
        public bool DownLoadProgram(string IPAddress, uint BagTotal, uint BagNum, byte[] FontLibBytes)
        {
            bool flag = false;
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            uint bagTotal = BagTotal;    //包总数 0
            uint bagNum = BagNum;    //当前包索引
            dictParams.Add("bagTotal", bagTotal);
            dictParams.Add("bagNum", bagNum);
            dictParams.Add("bagBuff", FontLibBytes);
            flag = SendToUdp(IPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_PROGRAM_DOWNLOAD, dictParams);
            return flag;
        }

        /// <summary>
        /// 远程程序更新命令
        /// </summary>
        /// <param name="IPAddress">一体机IP</param>
        /// <param name="ProgramLength">程序大小</param>
        /// <returns></returns>
        public bool SendRemoteUpdate(string IPAddress, uint ProgramLength)
        {
            bool flag = false;
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("ProgramLength", ProgramLength);
            flag = SendToUdp(IPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_PROGRAM_UPDATE, dictParams);
            return flag;
        }

        /// <summary>
        /// 发送LED（64*128）显示或配置
        /// </summary>
        /// <param name="ip">一体机IP</param>
        /// <param name="keepTime">发布的内容保持时间范围0~255，单位秒，超时之后恢复默认显示；等于0时，表示内容保持时间无限长；</param>
        /// <param name="freshTime">多屏显示切换时间，单位秒，范围1至60</param>
        /// <param name="OneMsg">第一行显示内容（8字节倍数）</param>
        /// <param name="TwoMsg">第二行显示内容（8字节倍数）</param>
        /// <param name="ThreeMsg">第三行显示内容（8字节倍数），若三、四行合并显示此参数只能输入数字类型字符串且范围应在9999以内,不足四位请在高位补0,如：0008</param>
        /// <param name="FourMsg">第四行显示内容（8字节倍数）</param>
        /// <param name="cmdType">设置命令类型：00-查询屏幕类型 01-设置屏幕类型 02-发布显示内容 03-发布默认显示内容（断电保存） 04-发布默认显示内容（断电不保存）</param>
        /// <param name="ThreeFourBind">第三第四行合并一行显示：0 分行（默认）；1 分行显示日期及时间；2 金额****（并行）；3 余****天（并行）；4 余****元（并行）；5 余****位（并行）所有合并行数值都填入参数 ThreeMsg </param>
        /// <param name="OneShowTime">第一行是否显示时间：0 不显示；1 显示；</param>
        /// <param name="OneTimePos">第一行日期显示位置：0 内容前；1 内容后；</param>
        /// <param name="OneTimeFormat">内容格式：0 yy年MM月dd日；1 yy-MM-dd；2 yy/MM/dd；3 yy.MM.dd；4 H时mm分ss秒 (24小时制)；5 HH时mm分ss秒 (12小时制)；6 HH:mm:ss (24小时制)；7 H:mm:ss (12小时制)；</param>
        /// <param name="TwoShowTime">第二行是否显示时间：0 不显示；1 显示；</param>
        /// <param name="TwoTimePos">第二行日期显示位置：0 内容前；1 内容后；</param>
        /// <param name="TwoTimeFormat">第二行内容格式：0 yy年MM月dd日；1 yy-MM-dd；2 yy/MM/dd；3 yy.MM.dd；4 H时mm分ss秒 (24小时制)；5 HH时mm分ss秒 (12小时制)；6 HH:mm:ss (24小时制)；7 H:mm:ss (12小时制)；</param>
        /// <param name="ThreeShowTime">第三行是否显示时间：0 不显示；1 显示；</param>
        /// <param name="ThreeTimePos">第三行日期显示位置：0 内容前；1 内容后；</param>
        /// <param name="ThreeTimeFormat">第三行内容格式：0 yy年MM月dd日；1 yy-MM-dd；2 yy/MM/dd；3 yy.MM.dd；4 H时mm分ss秒 (24小时制)；5 HH时mm分ss秒 (12小时制)；6 HH:mm:ss (24小时制)；7 H:mm:ss (12小时制)；</param>
        /// <param name="FourShowTime">第四行是否显示时间：0 不显示；1 显示；</param>
        /// <param name="FourTimePos">第四行日期显示位置：0 内容前；1 内容后；</param>
        /// <param name="FourTimeFormat">第四行内容格式：0 yy年MM月dd日；1 yy-MM-dd；2 yy/MM/dd；3 yy.MM.dd；4 H时mm分ss秒 (24小时制)；5 HH时mm分ss秒 (12小时制)；6 HH:mm:ss (24小时制)；7 H:mm:ss (12小时制)；</param>
        /// <param name="OneEffect">第一行动画特效：0-静态多屏切换；2-左移；3-静态左移(仅适用于屏类型64*128)</param>
        /// <param name="TwoEffect">第二行动画特效：0-静态多屏切换；2-左移；3-静态左移(仅适用于屏类型64*128)</param>
        /// <param name="ThreeEffect">第三行动画特效：0-静态多屏切换；2-左移；3-静态左移(仅适用于屏类型64*128)</param>
        /// <param name="FourEffect">第四行动画特效：0-静态多屏切换；2-左移；3-静态左移(仅适用于屏类型64*128)</param>
        /// <returns></returns>
        public bool SendSetLed64Ride128Show(string ip, int keepTime, int freshTime, string OneMsg, string TwoMsg, string ThreeMsg, string FourMsg, int cmdType = 2, int ThreeFourBind = 0, int OneShowTime = 0, int OneTimePos = 0, int OneTimeFormat = 0, int TwoShowTime = 0, int TwoTimePos = 0, int TwoTimeFormat = 0, int ThreeShowTime = 0, int ThreeTimePos = 0, int ThreeTimeFormat = 0, int FourShowTime = 0, int FourTimePos = 0, int FourTimeFormat = 0, int OneEffect = 0, int TwoEffect = 0, int ThreeEffect = 0, int FourEffect = 0)
        {

            Dictionary<string, object> dictParams = new Dictionary<string, object>();

            dictParams.Add("uCommand", cmdType);
            dictParams.Add("uSelectedIndex", 3); //0-16*64点阵屏,1-32*64点阵屏,3-64*128点阵屏
            dictParams.Add("uKeepTime", keepTime);
            dictParams.Add("uReserve", 0);
            dictParams.Add("ThreeFourBind", ThreeFourBind); //3、4行合并显示
            //第一行
            dictParams.Add("uLineNumber", 0);
            dictParams.Add("uLedScreenSum", 0);
            dictParams.Add("OneEffect", OneEffect); //特效
            dictParams.Add("uLedChangeTime", freshTime);
            dictParams.Add("uLedMsg", OneMsg);
            dictParams.Add("OneShowTime", OneShowTime);
            dictParams.Add("OneTimePos", OneTimePos);
            dictParams.Add("OneTimeFormat", OneTimeFormat);

            //第二行
            dictParams.Add("uLineNumber2", 1);
            dictParams.Add("uLedScreenSum2", 0);
            dictParams.Add("TwoEffect", TwoEffect); //特效
            dictParams.Add("uLedChangeTime2", freshTime);
            dictParams.Add("uLedMsg2", TwoMsg);
            dictParams.Add("TwoShowTime", TwoShowTime);
            dictParams.Add("TwoTimePos", TwoTimePos);
            dictParams.Add("TwoTimeFormat", TwoTimeFormat);

            //第三行
            dictParams.Add("uLineNumber3", 2);
            dictParams.Add("uLedScreenSum3", 0);
            dictParams.Add("ThreeEffect", ThreeEffect); //特效
            dictParams.Add("uLedChangeTime3", freshTime);
            dictParams.Add("uLedMsg3", ThreeMsg);
            dictParams.Add("ThreeShowTime", ThreeShowTime);
            dictParams.Add("ThreeTimePos", ThreeTimePos);
            dictParams.Add("ThreeTimeFormat", ThreeTimeFormat);

            //第四行
            dictParams.Add("uLineNumber4", 3);
            dictParams.Add("uLedScreenSum4", 0);
            dictParams.Add("FourEffect", FourEffect); //特效
            dictParams.Add("uLedChangeTime4", freshTime);
            dictParams.Add("uLedMsg4", FourMsg);
            dictParams.Add("FourShowTime", FourShowTime);
            dictParams.Add("FourTimePos", FourTimePos);
            dictParams.Add("FourTimeFormat", FourTimeFormat);
            return SendSetLed(ip, dictParams);
        }


        /// <summary>
        /// 全屏点亮
        /// </summary>
        /// <param name="IpAddress">一体机IP</param>
        /// <param name="LedType">0 16*64点阵屏,1 32*64点阵屏,2 32*128(保留),3 64*128点阵屏</param>
        /// <param name="keepTime">默认10秒</param>
        /// <returns></returns>
        public bool SetLedLightOnAll(string IpAddress, int LedType)
        {
            bool flag = false;
            List<byte> buff = new List<byte>();
            List<byte> contentON = new List<byte>() { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
            byte[] buffHead = new byte[] { 0xB6, 0x6B, 0xFF, 0xBB, 0x33, 0x00, 0x00, 0x00, 0xE7, 0x03, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0xC5, 0xB0, 0xB3 };
            buff.AddRange(buffHead);
            buff.AddRange(new byte[] { 0x03, (byte)LedType, 0x00, 0x00 }); //屏类型，显示类型即时、默认，显示时间

            switch (LedType)
            {
                default:
                case 0:
                    buff.AddRange(new byte[] { 0x00, 0x01, 0x00, 0x05 }); //第一行设置
                    buff.AddRange(contentON);
                    break;
                case 1:
                    buff.AddRange(new byte[] { 0x00, 0x01, 0x00, 0x05 }); //第一行设置
                    buff.AddRange(contentON);
                    buff.AddRange(new byte[] { 0x01, 0x01, 0x00, 0x05 }); //第二行设置
                    buff.AddRange(contentON);
                    break;
                case 2: //保留
                    buff = new List<byte>();
                    break;
                case 3:
                    buff.AddRange(new byte[] { 0x00, 0x01, 0x00, 0x05 }); //第一行设置
                    buff.AddRange(contentON);
                    buff.AddRange(new byte[] { 0x01, 0x01, 0x00, 0x05 }); //第二行设置
                    buff.AddRange(contentON);
                    buff.AddRange(new byte[] { 0x02, 0x01, 0x00, 0x05 }); //第三行设置
                    buff.AddRange(contentON);
                    buff.AddRange(new byte[] { 0x03, 0x01, 0x00, 0x05 }); //第四行设置
                    buff.AddRange(contentON);
                    break;
            }

            UdpAsyncClient.SendData(IpAddress, buff.ToArray());
            Common.Log(string.Format("发送：{0}", Common.BytesToHex(buff.ToArray())));
            flag = true;
            return flag;
        }

        /// <summary>
        /// 出入口车位引导屏设置命令
        /// </summary>
        /// <param name="IPAddress">一体机IP</param>
        /// <param name="LedId">出入口引导屏地址 范围 0~99 </param>
        /// <param name="LedColor">范围 0~3 0-红色，1-绿色，2-黄色，3-自动（内容为0时红色，不为0时绿色）</param>
        /// <param name="GuidWay">范围 0~7 箭头在数字后:0-右,1-上，2-左，3-下 箭头在数字前:4-右,5-上，6-左，7-下 </param>
        /// <param name="ShowNum">车位数量（总车位、剩余） 范围 0000~0999 注：最高位不显示，不参与数据判断，是扩展位，兼容后续程序，范围0至9 </param>
        /// <returns></returns>

        public bool SendSetGuidLed(string IPAddress, int LedId, int LedColor, int GuidWay, int ShowNum)
        {
            bool flag = false;
            Dictionary<string, object> dictParams = new Dictionary<string, object>();
            dictParams.Add("LedId", LedId);
            dictParams.Add("LedColor", LedColor);
            dictParams.Add("GuidWay", GuidWay);
            dictParams.Add("ShowNum", ShowNum);
            flag = SendToUdp(IPAddress, InfoEnumClass.EmCommandID.CMD_PARK_SET_GUID_LED, dictParams);
            return flag;
        }

        /// <summary>
        /// 通过UDP发送指令
        /// </summary>
        /// <param name="ip">一体机IP</param>
        /// <param name="commandID">命令ID</param>
        /// <param name="dict">命令数据</param>
        /// <param name="isBrodcast">是否广播：true 广播；false 单播</param>
        /// <returns></returns>
        private bool SendToUdp(string ip, InfoEnumClass.EmCommandID commandID, Dictionary<string, object> dict, bool isBrodcast = false)
        {
            InfoPacket packet = new InfoPacket();
            packet.head.uCommandID = (uint)commandID;
            packet.body = dict;
            //InfoRef result = su.SendData(packet, isBrodcast);
            InfoRef result = UdpAsyncClient.SendData(ip, packet, isBrodcast);
            if (result.State == InfoEnumClass.emState.Succeed)
            {

                //发送成功
                return true;
            }

            //发送失败
            return false;
        }

        public void Dispose()
        {

        }
    }
}
